package com.ruoyi.biz.strategy.impl;

import com.ruoyi.biz.domain.BizGoodsCategory;
import com.ruoyi.biz.domain.BizGoodsCategoryStrategy;
import com.ruoyi.biz.domain.dto.CaculateGoodsDto;
import com.ruoyi.biz.domain.vo.CaculateGoodsVo;
import com.ruoyi.biz.enums.CaculateTypeEnum;
import com.ruoyi.biz.mapper.BizGoodsCategoryStrategyMapper;
import com.ruoyi.biz.strategy.IGoodsCategoryCaculateStrategy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author tds
 * @version 1.0.0
 * @Company
 * @ClassName DefaultGoodsCategoryStrategy
 * @Description 商品类别区间价格计算策略
 * @Date 2022-11-10 22:59
 */
@Component("goodsCategorySectionPriceStrategy")
public class GoodsCategorySectionPriceStrategy implements IGoodsCategoryCaculateStrategy {

    @Resource
    private BizGoodsCategoryStrategyMapper categoryStrategyMapper;

    /**
     * 计算商品类别价格信息
     *
     * @param caculateGoodsDto 商品类别价格信息
     * @param goodsCategory 商品类别信息
     * @return
     */
    @Override
    public CaculateGoodsVo caculate(CaculateGoodsDto caculateGoodsDto, BizGoodsCategory goodsCategory) {
        // 折扣
        BigDecimal discount = caculateGoodsDto.getDiscount();
        // 面积
        BigDecimal size = caculateGoodsDto.getSize();

        // 查询商品价格区间
        List<BizGoodsCategoryStrategy> categoryStrategies = categoryStrategyMapper.selectByGoodsId(goodsCategory.getGoodsId());

        // 折扣小于等于0 或 面积小于等于0
        if (discount.compareTo(BigDecimal.ZERO) <= 0
                || size.compareTo(BigDecimal.ZERO) <= 0) {
            discount = BigDecimal.ZERO;
            size = BigDecimal.ZERO;
        }

        // 折扣前价格
        BigDecimal totalMoney = BigDecimal.ZERO;

        for (BizGoodsCategoryStrategy categoryStrategy : categoryStrategies) {
            // 面积小于区间下限，就不用计算，结束
            if (categoryStrategy.getMinVal().compareTo(caculateGoodsDto.getSize()) > 0) {
                break;
            }

            // 本区间面积 = 面积是否大于区间上限 ？ (区间上限 - 区间下限) : (面积 - 区间下限)
            BigDecimal theSize = size.compareTo(categoryStrategy.getMaxVal()) > 0 ?
                    categoryStrategy.getMaxVal().subtract(categoryStrategy.getMinVal()) :
                    size.subtract(categoryStrategy.getMinVal());

            // 本区间价格 = 单价 * 本区间面积
            BigDecimal money = categoryStrategy.getPrice().multiply(theSize);

            totalMoney = totalMoney.add(money);
        }
        totalMoney = totalMoney.setScale(2, BigDecimal.ROUND_HALF_UP);

        // 折扣价格 = 折扣前价格 * 折扣 / 10
        BigDecimal discountMoney = totalMoney.multiply(discount).divide(new BigDecimal(10));

        // 最终价格 = 总价 - 折扣价格
        BigDecimal finalMoney = totalMoney.subtract(discountMoney);

        return CaculateGoodsVo.builder()
                .totalMoney(totalMoney)
                .discountMoney(discountMoney)
                .finalMoney(finalMoney)
                .build();
    }

    /**
     * 获取计算类型
     *
     * @return
     */
    @Override
    public String getType() {
        return CaculateTypeEnum.SECTION_PRICE.getCode();
    }
}
